package com.teamone.mobilewatch;

import java.util.ArrayList;
import java.util.Locale;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.teamone.mobilewatch.model.Patient;
import com.teamone.mobilewatch.model.PatientReadings;
import com.teamone.mobilewatch.model.Watchlist;
import com.teamone.mobilewatch.model.WatchlistUpdater;
import com.teamone.mobilewatch.util.PatientState;
import com.teamone.mobilewatch.util.PatientStateAnalyzer;
import com.teamone.mobilewatch.util.UserSettings;

/**
 * Patientwatch screen to monitor patients registered in the watchlist
 * 
 */
public class PatientWatchActivity extends Activity implements OnInitListener {

	private static final String TAG = "PatientWatch";
	private TextToSpeech tts;
	private boolean ttsInitialized = false; 

	private PatientReadingsAdapter adapter;
	private Watchlist watchlist;

	WatchlistUpdater watchlistUpdater;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.patientwatch);
		//------tts
		if (UserSettings.isVoiceAlerts()) {
			tts = new TextToSpeech(this, this);
		}

		watchlist = Watchlist.getInstance();
		watchlist.loadFromPersistence(this); // loads previously saved data

		watchlistUpdater = new WatchlistUpdater(watchlist, this);

		ArrayList<Patient> patients = new ArrayList<Patient>();

		this.adapter = new PatientReadingsAdapter(this,
				R.layout.list_item_two_line_img, patients);
		ListView lstPatients = (ListView) findViewById(R.id.lstPatients);
		lstPatients.setAdapter(adapter);
		lstPatients.setItemsCanFocus(false);
		lstPatients.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
		// add listener to handle selection
		lstPatients.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View view,
					int position, long id) {
				Log.d(TAG, "onItemClick arg2=" + position + "id=" + id + "tag="
						+ view.getTag());
				int patientId = (Integer) view.getTag(); // read id from the tag
				// open DetailsActivity to display information for selected
				// patient
				watchlist.setSelectedId(patientId);
				startActivity(new Intent(getBaseContext(),
						DetailsActivity.class));
			}
		});
	}

	@Override
	protected void onResume() {
		super.onResume();
		// sync with watchlist
		watchlistUpdater.start();
	}

	@Override
	protected void onStop() {
		super.onStop();
	}

	@Override
	public void onDestroy() {
		if (tts != null) {
			tts.stop();
			tts.shutdown();
		}
		watchlistUpdater.stop();
		super.onDestroy();
	}

	@Override
	public void onInit(int status) {
		if (status == TextToSpeech.SUCCESS) {
			Toast.makeText(PatientWatchActivity.this,
					"Text-To-Speech engine is initialized", Toast.LENGTH_LONG)
					.show();
			ttsInitialized = true;
		} else if (status == TextToSpeech.ERROR) {
			Toast.makeText(PatientWatchActivity.this,
					"Error occurred while initializing Text-To-Speech engine",
					Toast.LENGTH_LONG).show();
		}

		if (status == TextToSpeech.SUCCESS) {
			int result = tts.setLanguage(Locale.US);
			if (result == TextToSpeech.LANG_MISSING_DATA
					|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
				// Lanuage data is missing or the language is not supported.
				Log.e(TAG, "Language is not available.");
			} else {
				Log.e(TAG, "Text-To-Speech set language error.");
				// Check the documentation for other possible result codes.
			}
		} else {
			// Initialization failed.
			Log.e(TAG, "Could not initialize TextToSpeech.");
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {

		case R.id.edit:
			startActivity(new Intent(this, EditActivity.class));
			return true;

		case R.id.details:
			startActivity(new Intent(this, DetailsActivity.class));
			return true;

		case R.id.settings:
			startActivity(new Intent(this, SettingsPreferenceActivity.class));
			return true;

		case R.id.admin:
			startActivity(new Intent(this, AdminActivity.class));
			return true;

		default:
			break;
		}

		return false;
	}

	/**
	 * Updates adapter of listview with latest readings
	 * @param patients
	 */
	public void updateAdapter(ArrayList<Patient> patients) {
		// update adapter
		adapter.clear();
		if (patients != null && patients.size() > 0) {
			for (int i = 0; i < patients.size(); i++) {
				adapter.add(patients.get(i));
			}

		} else {
			Toast.makeText(
					getApplicationContext(),
					"No patients currently added to PatientWatch. Please select from menu Edit to add patients to PatientWatch.",
					Toast.LENGTH_LONG).show();
		}
		adapter.notifyDataSetChanged();
	}

	/**
	 * Voice alert about patients in critical condition
	 * @param patients
	 */
	public void voiceAlertCriticalCondition(ArrayList<Patient> patients) {
		if (tts != null && ttsInitialized) {
			for (Patient p : patients) {
				PatientState state = PatientStateAnalyzer.process(p
						.getLastPatientReadings());
				if (state == PatientState.CRITICAL) {
					// ---text-to-speech
					String text = String.format("%s %s in critical condition",
							p.getFirstName(), p.getLastName());
					tts.speak(text, TextToSpeech.QUEUE_ADD, null);
				}
			}
		}
	}

	/**
	 * Extension of ArrayAdapter for custom two lines & image ListView
	 * 
	 */
	private class PatientReadingsAdapter extends ArrayAdapter<Patient> {

		private ArrayList<Patient> items;

		public PatientReadingsAdapter(Context context, int textViewResourceId,
				ArrayList<Patient> items) {
			super(context, textViewResourceId, items);
			this.items = items;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View v = convertView;
			if (v == null) {
				LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
				v = vi.inflate(R.layout.list_item_two_line_img, null);
			}
			Patient p = items.get(position);
			if (p != null) {
				TextView txt1 = (TextView) v.findViewById(R.id.txtLine1);
				TextView txt2 = (TextView) v.findViewById(R.id.txtLine2);
				ImageView imgState = (ImageView) v.findViewById(R.id.imgState);
				// line1
				if (txt1 != null) {
					txt1.setText(p.getFirstName() + " " + p.getLastName());
				}
				// line2 - text
				if (txt2 != null) {
					PatientReadings readings = p.getLastPatientReadings();
					String readingsStr = "Data Not Available";
					if (readings != null) {
						readingsStr = String.format("BP:%d/%d, HR:%d, t:%.1f",
								readings.getBph(), readings.getBpl(),
								readings.getHr(), readings.getT() / 10.0);
					}
					txt2.setText(readingsStr);
				}
				// line 2 - state icon
				PatientState state = PatientStateAnalyzer.process(p
						.getLastPatientReadings());
				int imgResId = state.getIconId();
				imgState.setImageResource(imgResId);

				v.setTag(new Integer(p.getPatientId()));
			}
			return v;
		}
	}
}
